import { _decorator, Component, director, instantiate, Node, Prefab } from 'cc'
import { ApiMsgEnum, IApiPlayerListRes, IApiRoomListRes } from '../Common'
import { EventEnum, SceneEnum } from '../Enum'
import DataManager from '../Global/DataManager'
import EventManager from '../Global/EventManager'
import { NetworkManager } from '../Global/NetworkManager'
import { PlayerManager } from '../UI/PlayerManager'
import { RoomManager } from '../UI/RoomManager'
const { ccclass, property } = _decorator

@ccclass('HallManager')
export class HallManager extends Component {
  @property(Node)
  playerContainer: Node

  @property(Prefab)
  playerPrefab: Prefab

  @property(Node)
  roomContainer: Node

  @property(Prefab)
  roomPrefab: Prefab

  onLoad() {
    NetworkManager.Instance.listenMsg(ApiMsgEnum.MsgPlayerList, this.renderPlayer, this)
    NetworkManager.Instance.listenMsg(ApiMsgEnum.MsgRoomList, this.renderRoom, this)
    EventManager.Instance.on(EventEnum.RoomJoin, this.handleJoinRoom, this)
  }

  start() {
    this.playerContainer.destroyAllChildren()
    this.roomContainer.destroyAllChildren()
    this.getPlayers()
    this.getRooms()
  }

  onDestroy() {
    NetworkManager.Instance.unListenMsg(ApiMsgEnum.MsgPlayerList, this.renderPlayer, this)
    NetworkManager.Instance.unListenMsg(ApiMsgEnum.MsgRoomList, this.renderRoom, this)
    EventManager.Instance.off(EventEnum.RoomJoin, this.handleJoinRoom, this)
  }

  async getPlayers() {
    const { success, res, error } = await NetworkManager.Instance.callApi(ApiMsgEnum.ApiPlayerList, {})
    if (!success) {
      console.log(error)
      return
    }
    this.renderPlayer(res)
  }

  renderPlayer({ list }: IApiPlayerListRes) {
    for (const child of this.playerContainer.children) {
      child.active = false
    }

    while (this.playerContainer.children.length < list.length) {
      const node = instantiate(this.playerPrefab)
      node.active = false
      node.setParent(this.playerContainer)
    }

    for (let i = 0; i < list.length; i++) {
      const player = list[i]
      const node = this.playerContainer.children[i]
      node.getComponent(PlayerManager).init(player)
    }
  }

  async handleCreateRoom() {
    const { success, error, res } = await NetworkManager.Instance.callApi(ApiMsgEnum.ApiRoomCreate, {})
    if (!success) {
      console.log(error)
      return
    }

    DataManager.Instance.roomInfo = res.room
    director.loadScene(SceneEnum.Room)
  }

  async handleJoinRoom(rid: number) {
    const { success, error, res } = await NetworkManager.Instance.callApi(ApiMsgEnum.ApiRoomJoin, { rid })
    if (!success) {
      console.log(error)
      return
    }

    DataManager.Instance.roomInfo = res.room
    director.loadScene(SceneEnum.Room)
  }

  async getRooms() {
    const { success, res, error } = await NetworkManager.Instance.callApi(ApiMsgEnum.ApiRoomList, {})
    if (!success) {
      console.log(error)
      return
    }
    this.renderRoom(res)
  }

  renderRoom({ list }: IApiRoomListRes) {
    for (const child of this.roomContainer.children) {
      child.active = false
    }

    while (this.roomContainer.children.length < list.length) {
      const node = instantiate(this.roomPrefab)
      node.active = false
      node.setParent(this.roomContainer)
    }

    for (let i = 0; i < list.length; i++) {
      const room = list[i]
      const node = this.roomContainer.children[i]
      node.getComponent(RoomManager).init(room)
    }
  }
}
